import pygame
import sys
import random

# 初始化pygame
pygame.init()
pygame.font.init()

# 游戏窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("飞机大战")

# 确保中文能正常显示
font = pygame.font.SysFont(['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC'], 36)
small_font = pygame.font.SysFont(['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC'], 24)

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)


# 玩家飞机类
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((50, 40), pygame.SRCALPHA)
        pygame.draw.polygon(self.image, BLUE, [(25, 0), (0, 40), (50, 40)])
        self.rect = self.image.get_rect()
        self.rect.x = WIDTH // 2 - self.rect.width // 2
        self.rect.y = HEIGHT - self.rect.height - 20
        self.speed = 8
        self.health = 3
        self.shoot_delay = 250
        self.last_shot = pygame.time.get_ticks()

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT] and self.rect.x > 0:
            self.rect.x -= self.speed
        if keys[pygame.K_RIGHT] and self.rect.x < WIDTH - self.rect.width:
            self.rect.x += self.speed
        if keys[pygame.K_UP] and self.rect.y > 0:
            self.rect.y -= self.speed
        if keys[pygame.K_DOWN] and self.rect.y < HEIGHT - self.rect.height:
            self.rect.y += self.speed

    def shoot(self):
        now = pygame.time.get_ticks()
        if now - self.last_shot > self.shoot_delay:
            self.last_shot = now
            bullet = Bullet(self.rect.centerx, self.rect.top)
            all_sprites.add(bullet)
            bullets.add(bullet)
            # 射击音效
            shoot_sound.play()


# 敌机类
class Enemy(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((40, 40), pygame.SRCALPHA)
        pygame.draw.polygon(self.image, RED, [(20, 0), (0, 20), (40, 20), (20, 0), (20, 40)])
        self.rect = self.image.get_rect()
        self.rect.x = random.randrange(WIDTH - self.rect.width)
        self.rect.y = random.randrange(-100, -40)
        self.speedy = random.randrange(3, 7)
        self.speedx = random.randrange(-3, 3)

    def update(self):
        self.rect.y += self.speedy
        self.rect.x += self.speedx
        if (self.rect.top > HEIGHT + 10 or
                self.rect.left < -25 or
                self.rect.right > WIDTH + 25):
            self.rect.x = random.randrange(WIDTH - self.rect.width)
            self.rect.y = random.randrange(-100, -40)
            self.speedy = random.randrange(3, 7)
            self.speedx = random.randrange(-3, 3)


# 子弹类
class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((6, 20), pygame.SRCALPHA)
        pygame.draw.rect(self.image, YELLOW, (0, 0, 6, 20))
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.bottom = y
        self.speedy = -15

    def update(self):
        self.rect.y += self.speedy
        if self.rect.bottom < 0:
            self.kill()


# 爆炸动画类
class Explosion(pygame.sprite.Sprite):
    def __init__(self, center, size=50):
        super().__init__()
        self.size = size
        self.image = pygame.Surface((self.size, self.size), pygame.SRCALPHA)
        self.rect = self.image.get_rect()
        self.rect.center = center
        self.frame = 0
        self.last_update = pygame.time.get_ticks()
        self.frame_rate = 50  # 帧速率，控制爆炸动画速度
        self.colors = [YELLOW, RED, (200, 50, 50), (150, 50, 50)]
        self.update_explosion_frame()

    def update_explosion_frame(self):
        self.image.fill((0, 0, 0, 0))  # 清除图像
        radius = int(self.size / 2 * (1 - self.frame / 8))
        if radius < 2:
            radius = 2
        color = self.colors[min(self.frame // 2, len(self.colors) - 1)]
        pygame.draw.circle(self.image, color, (self.size // 2, self.size // 2), radius)
        # 添加一些火花效果
        for _ in range(8 - self.frame):
            spark_len = random.randint(5, 15)
            angle = random.uniform(0, 2 * 3.14159)
            end_x = self.size // 2 + int(
                spark_len * 3.14159 * (1 - self.frame / 8) * pygame.math.Vector2(1, 0).rotate_rad(angle).x)
            end_y = self.size // 2 + int(
                spark_len * 3.14159 * (1 - self.frame / 8) * pygame.math.Vector2(1, 0).rotate_rad(angle).y)
            pygame.draw.line(self.image, YELLOW, (self.size // 2, self.size // 2), (end_x, end_y), 2)

    def update(self):
        now = pygame.time.get_ticks()
        if now - self.last_update > self.frame_rate:
            self.last_update = now
            self.frame += 1
            if self.frame >= 8:  # 8帧动画
                self.kill()
            else:
                self.update_explosion_frame()


# 创建精灵组
all_sprites = pygame.sprite.Group()
enemies = pygame.sprite.Group()
bullets = pygame.sprite.Group()

# 创建玩家
player = Player()
all_sprites.add(player)

# 创建敌机
for i in range(8):
    enemy = Enemy()
    all_sprites.add(enemy)
    enemies.add(enemy)

# 游戏变量
score = 0
game_over = False
game_start = True

# 加载音效（如果无法加载，会创建静默音效）
try:
    pygame.mixer.init()
    shoot_sound = pygame.mixer.Sound(pygame.mixer.Sound(pygame.mixer.Sound(pygame.mixer.Sound(b'\x00' * 1000))))
    explosion_sound = pygame.mixer.Sound(pygame.mixer.Sound(pygame.mixer.Sound(pygame.mixer.Sound(b'\x00' * 1000))))
    pygame.mixer.music.load(pygame.mixer.Sound(pygame.mixer.Sound(pygame.mixer.Sound(b'\x00' * 1000))))
    pygame.mixer.music.set_volume(0.2)
    pygame.mixer.music.play(-1)  # 循环播放背景音乐
except:
    # 如果音效初始化失败，创建空的音效对象
    class DummySound:
        def play(self):
            pass


    shoot_sound = DummySound()
    explosion_sound = DummySound()

# 游戏主循环
clock = pygame.time.Clock()
running = True

while running:
    clock.tick(60)

    # 处理输入事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                if not game_over and not game_start:
                    player.shoot()
            elif event.key == pygame.K_RETURN:
                if game_over or game_start:
                    # 重置游戏
                    game_over = False
                    game_start = False
                    score = 0
                    player.health = 3

                    # 清空精灵组
                    all_sprites.empty()
                    enemies.empty()
                    bullets.empty()

                    # 创建新玩家和敌机
                    player = Player()
                    all_sprites.add(player)
                    for i in range(8):
                        enemy = Enemy()
                        all_sprites.add(enemy)
                        enemies.add(enemy)

    if not game_over and not game_start:
        # 更新游戏
        all_sprites.update()

        # 检测子弹与敌机的碰撞
        hits = pygame.sprite.groupcollide(enemies, bullets, True, True)
        for hit in hits:
            score += 10
            explosion = Explosion(hit.rect.center)
            all_sprites.add(explosion)
            explosion_sound.play()
            enemy = Enemy()
            all_sprites.add(enemy)
            enemies.add(enemy)

        # 检测玩家与敌机的碰撞
        hits = pygame.sprite.spritecollide(player, enemies, True)
        for hit in hits:
            player.health -= 1
            explosion = Explosion(hit.rect.center)
            all_sprites.add(explosion)
            explosion_sound.play()
            enemy = Enemy()
            all_sprites.add(enemy)
            enemies.add(enemy)
            if player.health <= 0:
                explosion = Explosion(player.rect.center, 100)
                all_sprites.add(explosion)
                explosion_sound.play()
                player.kill()
                game_over = True

    # 绘制游戏
    screen.fill(BLACK)

    if game_start:
        # 显示开始界面
        title_text = font.render("飞机大战", True, WHITE)
        start_text = small_font.render("按Enter键开始游戏", True, WHITE)
        instruction_text = small_font.render("方向键移动，空格键射击", True, WHITE)

        screen.blit(title_text, (WIDTH // 2 - title_text.get_width() // 2, HEIGHT // 3))
        screen.blit(start_text, (WIDTH // 2 - start_text.get_width() // 2, HEIGHT // 2))
        screen.blit(instruction_text, (WIDTH // 2 - instruction_text.get_width() // 2, HEIGHT // 2 + 50))

    elif game_over:
        # 显示游戏结束界面
        game_over_text = font.render("游戏结束", True, WHITE)
        score_text = font.render(f"得分: {score}", True, WHITE)
        restart_text = small_font.render("按Enter键重新开始", True, WHITE)

        screen.blit(game_over_text, (WIDTH // 2 - game_over_text.get_width() // 2, HEIGHT // 3))
        screen.blit(score_text, (WIDTH // 2 - score_text.get_width() // 2, HEIGHT // 2))
        screen.blit(restart_text, (WIDTH // 2 - restart_text.get_width() // 2, HEIGHT // 2 + 50))

    else:
        # 绘制游戏元素
        all_sprites.draw(screen)

        # 显示分数
        score_display = small_font.render(f"分数: {score}", True, WHITE)
        screen.blit(score_display, (10, 10))

        # 显示生命值
        health_display = small_font.render(f"生命值: {player.health}", True, WHITE)
        screen.blit(health_display, (10, 40))

    # 更新屏幕
    pygame.display.flip()

pygame.quit()
sys.exit()